package com.zmzncs.lmtc.module.promotion.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zmzncs.lmtc.common.pojo.enums.optionalvalue.promotion.MonthRentTypeEnum;
import com.zmzncs.lmtc.common.util.ExceptionUtil;
import com.zmzncs.lmtc.module.park.dao.ParkInfoDao;
import com.zmzncs.lmtc.module.park.pojo.parkinfo.ParkInfo;
import com.zmzncs.lmtc.module.promotion.dao.CustomizeRuleDao;
import com.zmzncs.lmtc.module.promotion.dao.CustomizeRuleFeeScaleDao;
import com.zmzncs.lmtc.module.promotion.dao.MonthRuleFeeScaleMapper;
import com.zmzncs.lmtc.module.promotion.pojo.customize_rule.CustomizeRule;
import com.zmzncs.lmtc.module.promotion.pojo.customize_rule.CustomizeRuleDTO;
import com.zmzncs.lmtc.module.promotion.pojo.customize_rule.CustomizeRuleUpdateForm;
import com.zmzncs.lmtc.module.promotion.pojo.customize_rule_fee_scale.CustomizeRuleFeeScale;
import com.zmzncs.lmtc.module.promotion.pojo.customize_rule_fee_scale.CustomizeRuleFeeScaleDTO;
import com.zmzncs.lmtc.module.promotion.pojo.customize_rule_fee_scale.CustomizeRuleFeeScaleMobileVO;
import com.zmzncs.lmtc.module.promotion.pojo.month_rule_fee_scale.MonthRuleFeeScaleDTO;
import com.zmzncs.lmtc.module.promotion.service.CustomizeRuleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author 任建波
 * @since 2020-08-13
 */
@Service
public class CustomizeRuleServiceImpl extends ServiceImpl<CustomizeRuleDao, CustomizeRule> implements CustomizeRuleService {

    @Autowired
    CustomizeRuleDao customizeRuleDao;
    @Autowired
    CustomizeRuleFeeScaleDao customizeRuleFeeScaleDao;
    @Autowired
    MonthRuleFeeScaleMapper monthRuleFeeScaleMapper;
    @Autowired
    ParkInfoDao parkInfoDao;

    /**
     * 计算定制卡价格
     */
    @Override
    public CustomizeRuleFeeScaleMobileVO computePrice(List<Long> parkIdList) {
        List<MonthRuleFeeScaleDTO> monthRuleFeeScaleAllList = new ArrayList<>();
        //  校验停车场收费标准
        for (Long parkId : parkIdList) {
            List<MonthRuleFeeScaleDTO> monthRulePaytypeList = monthRuleFeeScaleMapper.getMonthRuleFeeScaleByParkId(parkId, null);
            if (monthRulePaytypeList.size() == 0) {
                ExceptionUtil.businessException("停车场" + parkId + "没有开启月租服务");
            }

            ParkInfo parkInfo = parkInfoDao.selectById(parkId);
            if (parkInfo == null || !parkInfo.getIsShow().equals(1)) {
                ExceptionUtil.businessException("停车场" + parkId + "已停止服务或不存在");
            }

            if (monthRulePaytypeList.size() > 3) {
                //筛除多余月租规则数据
                monthRulePaytypeList = screenSurplusMonthRule(monthRulePaytypeList);
            }
            monthRuleFeeScaleAllList.addAll(monthRulePaytypeList);
        }

        //  *********************************停车场折率
        //  根据停车场数量查询定制规则的收费标准
        List<CustomizeRuleFeeScaleDTO> customizeRuleFeeScaleList = customizeRuleFeeScaleDao.getCustomizeRuleFeeScaleByParkNum(parkIdList.size());
        //  月付折率
        BigDecimal monthDiscountRate = getCustomizeRuleDiscountRate(customizeRuleFeeScaleList, MonthRentTypeEnum.MONTH);
        //  季付折率
        BigDecimal quarterDiscountRate = getCustomizeRuleDiscountRate(customizeRuleFeeScaleList, MonthRentTypeEnum.QUARTER);
        //  年付折率
        BigDecimal yearDiscountRate = getCustomizeRuleDiscountRate(customizeRuleFeeScaleList, MonthRentTypeEnum.YEAR);


        //  *********************************计算停车场费用
        //  月付收费标准
        List<MonthRuleFeeScaleDTO> monthRuleFeeScaleList = getMonthRuleFeeScale(monthRuleFeeScaleAllList, MonthRentTypeEnum.MONTH.getCode());
        //  季付收费标准
        List<MonthRuleFeeScaleDTO> quarterRuleFeeScaleList = getMonthRuleFeeScale(monthRuleFeeScaleAllList, MonthRentTypeEnum.QUARTER.getCode());
        //  年付收费标准
        List<MonthRuleFeeScaleDTO> yearRuleFeeScaleList = getMonthRuleFeeScale(monthRuleFeeScaleAllList, MonthRentTypeEnum.YEAR.getCode());

        //  月付金额计算：除去价格最高的停车场。剩余停车场费用总和
        BigDecimal monthTotalAmount;
        if (monthRuleFeeScaleList.size() == 0 || parkIdList.size() > monthRuleFeeScaleList.size()) {
            monthTotalAmount = null;
        } else {
            monthTotalAmount = totalAmount(monthRuleFeeScaleList, monthDiscountRate, MonthRentTypeEnum.MONTH);
        }
        //  季付金额计算：除去价格最高的停车场。剩余停车场费用总和
        BigDecimal quarterTotalAmount;
        if (quarterRuleFeeScaleList.size() == 0 || parkIdList.size() > quarterRuleFeeScaleList.size()) {
            quarterTotalAmount = null;
        } else {
            quarterTotalAmount = totalAmount(quarterRuleFeeScaleList, quarterDiscountRate, MonthRentTypeEnum.QUARTER);
        }
        //  年付金额计算：除去价格最高的停车场。剩余停车场费用总和
        BigDecimal yearTotalAmount;
        if (yearRuleFeeScaleList.size() == 0 || parkIdList.size() > yearRuleFeeScaleList.size()) {
            yearTotalAmount = null;
        } else {
            yearTotalAmount = totalAmount(yearRuleFeeScaleList, yearDiscountRate, MonthRentTypeEnum.YEAR);
        }

        CustomizeRuleFeeScaleMobileVO customizeRuleFeeScaleMobileVO = new CustomizeRuleFeeScaleMobileVO();
        customizeRuleFeeScaleMobileVO.setMonthTotalAmount(monthTotalAmount);
        customizeRuleFeeScaleMobileVO.setQuarterTotalAmount(quarterTotalAmount);
        customizeRuleFeeScaleMobileVO.setYearTotalAmount(yearTotalAmount);
        customizeRuleFeeScaleMobileVO.setCustomizeRuleId(customizeRuleFeeScaleList.get(0).getCustomizeRuleId());
        return customizeRuleFeeScaleMobileVO;
    }

    /**
     * 月、季、年收费标准
     */
    List<MonthRuleFeeScaleDTO> getMonthRuleFeeScale(List<MonthRuleFeeScaleDTO> monthRulePaytypeList, Integer paytype) {
        //  收费标准
        List<MonthRuleFeeScaleDTO> paytypes = new ArrayList<>();
        for (MonthRuleFeeScaleDTO monthRuleFeeScaleDTO : monthRulePaytypeList) {
            if (monthRuleFeeScaleDTO.getMonthRentType() == paytype) {
                paytypes.add(monthRuleFeeScaleDTO);
            }
        }

        //  降序
        Collections.sort(paytypes, (m1, m2) -> {
            BigDecimal diff = m2.getSumAmount().subtract(m1.getSumAmount());
            if (diff.compareTo(BigDecimal.ZERO) > 0) {
                return 1;
            } else if (diff.compareTo(BigDecimal.ZERO) < 0) {
                return -1;
            }
            return 0; //相等为0
        });
        return paytypes;
    }

    /**
     * 获取定制规则折率
     */
    BigDecimal getCustomizeRuleDiscountRate(List<CustomizeRuleFeeScaleDTO> customizeRuleFeeScaleDTOList, MonthRentTypeEnum monthRentTypeEnum) {
        for (CustomizeRuleFeeScaleDTO customizeRuleFeeScaleDTO : customizeRuleFeeScaleDTOList) {
            //  折率
            if (customizeRuleFeeScaleDTO.getMonthRentType().equals(monthRentTypeEnum.getCode())) {
                return customizeRuleFeeScaleDTO.getDiscountRate();
            }
        }
        ExceptionUtil.businessException("没有【" + monthRentTypeEnum.getMassage() + "】的定制规则折扣设置");
        return null;
    }

    /**
     * 总金额0
     */
    BigDecimal totalAmount(List<MonthRuleFeeScaleDTO> monthRuleFeeScaleDTOList, BigDecimal discountRate, MonthRentTypeEnum monthRentTypeEnum) {
        BigDecimal totalAmount = new BigDecimal(0);
        //  除最高价格停车场外的其他停车场费用总和
        for (int i = 0; i < monthRuleFeeScaleDTOList.size(); i++) {
            if (i == 0) {
                continue;
            }
            if (monthRuleFeeScaleDTOList.get(i).getMonthRentType() == monthRentTypeEnum.getCode()) {
                totalAmount = totalAmount.add(monthRuleFeeScaleDTOList.get(i).getSumAmount());
            }
        }

        //  除去价格最高的停车场后剩余停车场费用总和 * 折率
        totalAmount = totalAmount.multiply(discountRate.divide(new BigDecimal(100)));
        //  最大值 + 其他值
        totalAmount = monthRuleFeeScaleDTOList.get(0).getSumAmount().add(totalAmount);

        return totalAmount;
    }

    /**
     * 筛除多余无用的月租规则（单个车场单个类型多个规则）
     */
    List<MonthRuleFeeScaleDTO> screenSurplusMonthRule(List<MonthRuleFeeScaleDTO> list) {
        for (int i = 0; i < list.size(); i++) {
            for (int j = 0; j > list.size() - i; j++) {
                MonthRuleFeeScaleDTO scale = list.get(i);
                MonthRuleFeeScaleDTO dto = list.get(j);
                if (scale.getMonthRuleId() == dto.getMonthRuleId() && scale.getMonthRentType() == dto.getMonthRentType()) {
                    if (scale.getSumAmount().compareTo(dto.getSumAmount()) > -1) {
                        list.remove(j);
                        j--;
                    } else {
                        list.remove(i);
                        i--;
                    }
                }
            }
        }
        return list;
    }

}
